package cn.jhz.learn.community_dynamic.wbms.controller.api;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import cn.jhz.learn.community_dynamic.CommunityDynamicApplication;
import cn.jhz.learn.community_dynamic.common.bean.JsonData;
import cn.jhz.learn.community_dynamic.common.exception.RequestException;
import cn.jhz.learn.community_dynamic.dao.CommentJpaRepository;
import cn.jhz.learn.community_dynamic.dao.PostJpaRepository;
import cn.jhz.learn.community_dynamic.dao.UserJpaRepository;
import cn.jhz.learn.community_dynamic.manager.CommentManager;
import cn.jhz.learn.community_dynamic.model.CommentEntity;
import cn.jhz.learn.community_dynamic.service.CommentService;

import lombok.Getter;

@RestController
@RequestMapping("api/")
public class AuthCommentController {

    private final CommentManager commentManager;
    private final CommentService commentService;
    private final UserJpaRepository userJpaRepository;
    private final CommentJpaRepository commentJpaRepository;
    private final PostJpaRepository postJpaRepository;

    @Getter
    private class CommentView implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 670163548851069881L;
	private Integer id;
	private Date createTime;
	private String content;
	private Long userId;
	private Integer postId;
	private Byte status;

	private CommentView(CommentEntity entity) {
	    this.id = entity.getId();
	    this.createTime = entity.getCreateTime();
	    this.content = entity.getData();
	    this.userId = entity.getUser().getLoginId();
	    this.postId = entity.getPost().getId();
	    this.status = entity.getStatus();
	}
    }

    @Autowired
    public AuthCommentController(CommentManager commentManager, CommentService commentService,
	    CommentJpaRepository commentJpaRepository, PostJpaRepository postJpaRepository,
	    UserJpaRepository userJpaRepository) {
	super();
	this.commentManager = commentManager;
	this.commentService = commentService;
	this.commentJpaRepository = commentJpaRepository;
	this.postJpaRepository = postJpaRepository;
	this.userJpaRepository = userJpaRepository;
    }

    @GetMapping("auth/wbms/comment/all")
    @PreAuthorize("hasAuthority('comment::get_all')")
    public JsonData getAll(@RequestParam("page") Integer page, @RequestParam("size") Integer size) {
	return JsonData
		.newSuccessInstance(this.commentJpaRepository.findAll(PageRequest.of(page - 1, size)).map(this::adpt));
    }

    @GetMapping("auth/wbms/comment/post/all")
    @PreAuthorize("hasAuthority('comment::get_all_post')")
    public JsonData getAllByPostId(@RequestParam("post_id") Integer postId, @RequestParam("page") Integer page,
	    @RequestParam("size") Integer size) {
	return JsonData.newSuccessInstance(this.commentJpaRepository
		.findByPost(this.postJpaRepository.findById(postId).orElseThrow(() -> new RequestException("无效文章")),
			PageRequest.of(page - 1, size))
		.map(this::adpt));
    }

    @GetMapping("auth/wbms/comment/user/all")
    @PreAuthorize("hasAuthority('comment::get_all_user')")
    public JsonData getAllByUser(@RequestParam("user_id") Long userId, @RequestParam("page") Integer page,
	    @RequestParam("size") Integer size) {
	return JsonData
		.newSuccessInstance(
			this.commentJpaRepository
				.findByUser(this.userJpaRepository.findByLoginId(userId)
					.orElseThrow(() -> new RequestException("无效用户")), PageRequest.of(page, size))
				.map(this::adpt));
    }

    @GetMapping("auth/wbms/comment/{id}")
    @PreAuthorize("hasAuthority('comment::get')")
    public JsonData getById(@PathVariable("id") Integer id) {
	return JsonData.newSuccessInstance(this.adpt(this.commentJpaRepository.findById(id).get()));
    }

    @GetMapping("auth/wbms/comment/review/all")
    @PreAuthorize("hasAuthority('comment::get_all_review')")
    public JsonData getAllReview(@RequestParam("size") Integer size) {
	return JsonData.newSuccessInstance(this.commentService.getReviewCache(CommunityDynamicApplication.REVIEW_CACHE)
		.get().stream().map(this.commentJpaRepository::findById).map(Optional::get).map(this::adpt).limit(size)
		.collect(Collectors.toList()));
    }

    @PatchMapping(value = "auth/wbms/comment/status", consumes = "application/x-www-form-urlencoded")
    @PreAuthorize("hasAuthority('comment::patch')")
    public JsonData patch(@RequestParam("id") Integer id, @RequestParam("operate") Byte operate,
	    @RequestParam(value = "review") Boolean review) {

	if (review) {
	    List<Integer> cache = this.commentService.getReviewCache(CommunityDynamicApplication.REVIEW_CACHE).get();
	    cache.remove(id);
	    this.commentService.putReviewCache(CommunityDynamicApplication.REVIEW_CACHE, cache);
	}

	return JsonData.newSuccessInstance(this.adpt(this.commentManager.updateInstanceColumn(
		this.commentJpaRepository.findById(id).orElseThrow(() -> new RequestException("评论不存在")), operate)));
    }

    private CommentView adpt(CommentEntity entity) {
	CommentView view = this.new CommentView(entity);
	return view;
    }
}
